package com.opengate.base.authtoken;

import com.alibaba.fastjson.JSON;
import com.opengate.base.constants.AppConstants;
import com.opengate.base.contextholder.SpringContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 曳戈泰尔
 * @version 1.0
 * @description AuthToken工具类
 * @date 2023/4/26 8:58 PM
 */
public class AuthTokenHelper {

    /** StringRedisTemplate 从Spring容器中获取 */
    private static final StringRedisTemplate STRING_REDIS_TEMPLATE =
            SpringContextHolder.getBean(StringRedisTemplate.class);

    /**
     * 设置登录信息
     *
     * <p>最多登录1设备
     *
     * @param userId 用户id
     * @param loginTime 登录时间
     * @param token token
     */
    public static void setAuthToken(String userId, long loginTime, String token) {

        // 设置超时时间
        long expireTime = System.currentTimeMillis() + AppConstants.TOKEN_EXPIRED_TIME;

        // 新登录信息
        List<UserToken.UserDto> userDtos = new ArrayList<>(2);
        userDtos.add(
                new UserToken.UserDto()
                        .setLoginTime(loginTime)
                        .setExpireTime(expireTime)
                        .setToken(token));

        // 取缓存登录信息
        String key = AppConstants.U_LOGIN_USER_TOKEN + userId;
        //        String str = STRING_REDIS_TEMPLATE.opsForValue().get(key);
        //        // 登录信息不为空
        //        if (!StringUtils.isEmpty(str)) {
        //            // 获取当前登录用户信息
        //            List<UserToken.UserDto> cacheUserDtos =
        //                    JSON.parseObject(str, UserToken.class).getUserDtos();
        //
        //            // 按未过期排序
        //            List<UserToken.UserDto> sortUserDtos =
        //                    cacheUserDtos.stream()
        //                            .filter(t -> t.getExpireTime() > loginTime)
        //                            .sorted(
        //                                    Comparator.comparing(UserToken.UserDto::getExpireTime)
        //                                            .reversed())
        //                            .collect(Collectors.toList());
        //
        //            // sortUserDtos 不为空
        //            if (!sortUserDtos.isEmpty()) {
        //                userDtos.add(sortUserDtos.get(0));
        //            }
        //        }

        /// 缓存的登录信息为空，直接设置新缓存
        STRING_REDIS_TEMPLATE
                .opsForValue()
                .set(
                        key,
                        new UserToken().setUserDtos(userDtos).toString(),
                        expireTime,
                        TimeUnit.MILLISECONDS);
    }

    /**
     * 获取AuthToken
     *
     * @param userId 用户id
     * @param curTime 当前时间
     * @return UserDto
     */
    public static UserToken.UserDto getAuthToken(String userId, long curTime) {

        // 获取登录信息
        String key = AppConstants.U_LOGIN_USER_TOKEN + userId;
        String str = STRING_REDIS_TEMPLATE.opsForValue().get(key);

        // 无登录信息返回null
        if (StringUtils.isEmpty(str)) {
            return null;
        }

        // 格式化登录信息为列表
        List<UserToken.UserDto> cacheUserDtos =
                JSON.parseObject(str, UserToken.class).getUserDtos();

        // stream处理返回有效登录信息，否则返回null
        return cacheUserDtos.stream()
                .filter(t -> t.getExpireTime() > curTime)
                .findAny()
                .orElse(null);
    }

    /**
     * 刷新AuthToken
     *
     * @param userId 用户id
     * @param curTime 当前时间
     */
    public static void refreshAuthToken(String userId, long curTime) {

        // 获取登录信息
        String key = AppConstants.U_LOGIN_USER_TOKEN + userId;
        String str = STRING_REDIS_TEMPLATE.opsForValue().get(key);

        // 登录信息不为空
        if (!StringUtils.isEmpty(str)) {
            // 计算超时时间
            long expireTime = curTime + AppConstants.TOKEN_EXPIRED_TIME;

            // 格式化登录信息为列表
            List<UserToken.UserDto> cacheUserDtos =
                    JSON.parseObject(str, UserToken.class).getUserDtos();

            // 遍历设置新的超时时间
            for (UserToken.UserDto cacheUserDto : cacheUserDtos) {
                cacheUserDto.setExpireTime(expireTime);
            }

            // 设置到Redis
            STRING_REDIS_TEMPLATE
                    .opsForValue()
                    .set(
                            key,
                            new UserToken().setUserDtos(cacheUserDtos).toString(),
                            expireTime,
                            TimeUnit.MILLISECONDS);
        }
    }

    /**
     * 删除AuthToken
     *
     * @param userId 用户id
     */
    public static void removeAuthToken(String userId) {

        // 获取登录信息
        String key = AppConstants.U_LOGIN_USER_TOKEN + userId;
        String str = STRING_REDIS_TEMPLATE.opsForValue().get(key);

        // 登录信息为空，直接return
        if (StringUtils.isEmpty(str)) {
            return;
        }

        // 删除登录Redis信息
        STRING_REDIS_TEMPLATE.delete(key);
    }
}
